#region Copyright

// // The contents of this file are subject to the Mozilla Public License
// // Version 1.1 (the "License"); you may not use this file except in compliance
// // with the License. You may obtain a copy of the License at
// //   
// // http://www.mozilla.org/MPL/
// //   
// // Software distributed under the License is distributed on an "AS IS"
// // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// // License for the specific language governing rights and limitations under 
// // the License.
// //   
// // The Initial Developer of the Original Code is Robert Smyth.
// // Portions created by Robert Smyth are Copyright (C) 2008-2013.
// //   
// // All Rights Reserved.

#endregion

using System;
using System.Collections.Generic;
using NoeticTools.NWorkflow.Exceptions;


namespace NoeticTools.NWorkflow.ProgressMonitoring
{
    internal abstract class ProgressScopeBase : IProgressScope
    {
        protected readonly List<IProgressScope> ChildScopes = new List<IProgressScope>();
        private readonly IProgressScopeService _scopeService;

        protected ProgressScopeBase(IProgressScopeService scopeService, IProgressScope parent)
        {
            Parent = parent;
            _scopeService = scopeService;
        }

        public abstract string Name { get; }
        public IProgressScope Parent { get; private set; }

        public abstract double TotalCompleted { get; }

        public void AddStep(IStepRules stepRules)
        {
            foreach (var childScope in ChildScopes)
            {
                if (childScope.Name == stepRules.StepRulesName)
                {
                    throw new WorkflowProgressConfigurationException(
                        string.Format("A workflow step of the name '{0}' has already been added ot the progress scope.", stepRules.StepRulesName));
                }
            }
            ChildScopes.Add(new StepProgressScope(stepRules));
        }

        public void Enter(IProgressScope childScope)
        {
            ChildScopes.Add(childScope);
        }

        void IDisposable.Dispose()
        {
            _scopeService.Leave(this);
        }

        public abstract double UpdateWeights(double startingWeight);
    }
}